﻿//using ConsoleApp;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using EasyTest.Shared.EnumType;
using EasyTest.Shared.外部访问;
using Serilog;
using Serilog.Core;

namespace ZLGCANoptimize
{
    /// <summary>
    /// can工厂
    /// </summary>
    public class CanFactory
    {
        //const unsigned char*  iSeedArray,     /* Array for the seed [in] */
        //unsigned int          iSeedArraySize, /* Length of the array for the seed [in] */
        //const unsigned int    iSecurityLevel, /* Security level [in] */
        //const char*           iVariant,       /* Name of the active variant [in] */
        //unsigned char*        ioKeyArray,     /* Array for the key [in, out] */
        //unsigned int          iKeyArraySize,  /* Maximum length of the array for the key [in] */
        //unsigned int&         oSize           /* Length of the key [out] */
        [DllImport("seedAndKey.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        private static extern int GenerateKeyEx(
[In] byte[] iSeedArray,
uint iSeedArraySize,
uint iSecurityLevel,
byte[] iVariant,
[In, Out] byte[] ioKeyArray,
uint iKeyArraySize,
out uint oSize);

        static DeviceInfo[] kDeviceType =
           {
            new DeviceInfo(Define.ZCAN_USBCAN1, 1),
            new DeviceInfo(Define.ZCAN_USBCAN2, 2),
            new DeviceInfo(Define.ZCAN_USBCAN_E_U, 1),
            new DeviceInfo(Define.ZCAN_USBCAN_2E_U, 2),
            new DeviceInfo(Define.ZCAN_PCIECANFD_100U, 1),
            new DeviceInfo(Define.ZCAN_PCIECANFD_200U, 2),
            new DeviceInfo(Define.ZCAN_PCIECANFD_200U_EX,2),
            new DeviceInfo(Define.ZCAN_PCIECANFD_400U, 4),
            new DeviceInfo(Define.ZCAN_USBCANFD_200U, 2),
            new DeviceInfo(Define.ZCAN_USBCANFD_100U, 1),
            new DeviceInfo(Define.ZCAN_USBCANFD_MINI, 1),
            new DeviceInfo(Define.ZCAN_CANETTCP, 1),
            new DeviceInfo(Define.ZCAN_CANETUDP, 1),
            new DeviceInfo(Define.ZCAN_CANFDNET_200U_TCP, 2),
            new DeviceInfo(Define.ZCAN_CANFDNET_200U_UDP, 2),
            new DeviceInfo(Define.ZCAN_CANFDNET_400U_TCP, 4),
            new DeviceInfo(Define.ZCAN_CANFDNET_400U_UDP, 4),
            new DeviceInfo(Define.ZCAN_CANFDNET_800U_TCP, 8),
            new DeviceInfo(Define.ZCAN_CANFDNET_800U_UDP, 8),
            new DeviceInfo(Define.ZCAN_CLOUD, 1)
        };
        static uint[] kUSBCANFDAbit =
         {
            1000000, // 1Mbps
            800000, // 800kbps
            500000, // 500kbps
            250000, // 250kbps
            125000, // 125kbps
            100000, // 100kbps
            50000, // 50kbps
            800000, // 800kbps
        };
        static uint[] kUSBCANFDDbit =
        {
            5000000, // 5Mbps
            4000000, // 4Mbps
            2000000, // 2Mbps
            1000000, // 1Mbps
            800000, // 800kbps
            500000, // 500kbps
            250000, // 250kbps
            125000, // 125kbps
            100000, // 100kbps
        };
        const int NULL = 0;
        static int channel_index_ = 0;
        static bool m_bOpen;
        /// <summary>
        /// 设备号
        /// </summary>
        public static IntPtr device_handle_;
        /// <summary>
        /// 通道句柄
        /// </summary>
        public static IntPtr channel_handle_;
        static Recvdatathread recv_data_thread_;
        /// <summary>
        /// 通道索引
        /// </summary>
        public static int channel_index = 2;
        const int CANFD_BRS = 0x01; /* bit rate switch (second bitrate for payload data) */
        const int CANFD_ESI = 0x02; /* error state indicator of the transmitting node */
        ///<summary>
        /// </summary>打开设备
        /// <param name="type">1为400U，2为200U</param>
        /// <param name="road">设备索引</param>
        /// <returns></returns>
        public static bool OpenDevice(int type, uint road)
        {
            switch (type)
            {
                case 1:
                    device_handle_ = Method.ZCAN_OpenDevice(kDeviceType[15].device_type, road, 0);
                    if (NULL == (int)device_handle_)
                    {
                        MessageBox.Show("打开设备失败,请检查设备类型和设备索引号是否正确", "提示",
                                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return m_bOpen = false;
                    }
                    break;
                case 2:
                    device_handle_ = Method.ZCAN_OpenDevice(kDeviceType[13].device_type, road, 0);
                    if (NULL == (int)device_handle_)
                    {
                        MessageBox.Show("打开设备失败,请检查设备类型和设备索引号是否正确", "提示",
                                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return m_bOpen = false;
                    }
                    break;
                case 3:
                    device_handle_ = Method.ZCAN_OpenDevice(kDeviceType[8].device_type, road, 0);
                    if (NULL == (int)device_handle_)
                    {
                        MessageBox.Show("打开设备失败,请检查设备类型和设备索引号是否正确", "提示",
                                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return m_bOpen = false;
                    }
                    break;
            }
            return m_bOpen = true;
        }
        /// <summary>
        /// 初始化CAN
        /// </summary>
        /// <param name="id">0表示为服务器,1表示客户端</param>
        /// <param name="ip">ip地址</param>
        /// <param name="port">端口</param>
        /// <param name="channel_index1">通道索引</param>
        /// <returns></returns>
        public static bool InitCan(int id, string ip, string port, int channel_index1, string name)
        {
            if (!m_bOpen)
            {
                MessageBox.Show("设备还没打开", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            uint type = 0;
            switch (name)
            {
                case "400":
                    type = kDeviceType[15].device_type;
                    break;
                case "200":
                    type = kDeviceType[13].device_type;
                    break;
            }

            bool tcpDevice = type == Define.ZCAN_CANETTCP || type == Define.ZCAN_CANFDNET_400U_TCP || type == Define.ZCAN_CANFDNET_200U_TCP || type == Define.ZCAN_CANFDNET_800U_TCP;
            bool server = tcpDevice && id == 0;
            if (tcpDevice)
            {
                setNetMode();
                if (server)
                {
                    setLocalPort(port);
                }
                else
                {
                    setRemoteAddr(ip);
                    setRemotePort(port);
                }
            }
            else
            {
                setLocalPort(port);
                setRemoteAddr(ip);
                setRemotePort(port);
            }
            channel_index = channel_index1;
            ZCAN_CHANNEL_INIT_CONFIG config_ = new ZCAN_CHANNEL_INIT_CONFIG();
            IntPtr pConfig = Marshal.AllocHGlobal(Marshal.SizeOf(config_));
            Marshal.StructureToPtr(config_, pConfig, true);
            channel_handle_ = Method.ZCAN_InitCAN(device_handle_, (uint)channel_index, pConfig);
            Marshal.FreeHGlobal(pConfig);
            if (NULL == (int)channel_handle_)
            {
                MessageBox.Show("初始化CAN失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            return true;
        }

        public static string get3EKey01(byte[] iSeedArray, uint iSecurityLevel = 1)
        {
            //byte[] seedArray = new byte[] { 0x00, 0x02, 0x09, 0xee }; // 用于生成密钥的种子

            uint iSeedArraySize = (uint)iSeedArray.Length;

            //1 security_constant_extended
            //2 security_constant_program
            //0x61 security_constant_supier

            //uint iSecurityLevel = 0x61;
            // uint iSecurityLevel = 1;

            byte[] iVariant = new byte[1];
            byte[] ioKeyArray = new byte[4];
            uint iKeyArraySize = (uint)ioKeyArray.Length;
            uint oSize;

            int result = GenerateKeyEx(iSeedArray, iSeedArraySize, iSecurityLevel, iVariant, ioKeyArray, iKeyArraySize, out oSize);
            string key = "";
            //string key_test = "";
            //for (int i = 0; i < iKeyArraySize; i++)
            //{
            //    key_test += ($"{ioKeyArray[i]:X}");
            //}

            string keys = BitConverter.ToString(ioKeyArray);
            key = keys.Replace("-", "");
            //var keyArray = BitConverter.ToUInt32(ioKeyArray, 0);
            return key;

        }

        //public static uint getKey(byte[] iSeedArray)
        //{
        //    IntPtr hdll;
        //    IntPtr ptrIn = Marshal.StringToHGlobalAnsi("SeednKey.dll");
        //    hdll = LoadLibrary(ptrIn);
        //    if (hdll == IntPtr.Zero)
        //    {
        //        Console.WriteLine("SeednKey.dll can't find!");
        //        return 0;
        //    }
        //    else
        //    {
        //        IntPtr ptrInt = Marshal.StringToHGlobalAnsi("GenerateKeyEx");
        //        var detect = GetProcAddress(hdll, ptrInt);
        //        if (detect != null)
        //        {
        //            const uint iSeedArraySize = 4;
        //            ////byte[] iSeedArray = new byte[4] { 0x34, 0x58, 0x0b, 0xfd };

        //            uint iSecurityLevel = 1;
        //            string iVariant = null;//传输种子

        //            uint ioKeyArraySize = 4;
        //            byte[] ioKeyArray = new byte[ioKeyArraySize];
        //            uint ret = 0;

        //            int result = GenerateKeyEx(iSeedArray, iSeedArraySize, iSecurityLevel, iVariant, ioKeyArray, ioKeyArraySize, ref ret);
        //            string key = "";
        //            for (int i = 0; i < ioKeyArraySize; i++)
        //            {
        //                key += ($"{ioKeyArray[i]:X}");
        //            }
        //            var keyArray = BitConverter.ToUInt32(ioKeyArray, 0);
        //            return keyArray;
        //        }
        //    }
        //    return 0;
        //}
        /// <summary>
        /// 初始化CAN
        /// </summary>
        /// <param name="mode">工作模式，0正常，1只听</param>
        /// <param name="channel_index1">通道索引</param>
        /// <param name="index">CANFD标准，0CANFD ISO,1BOSCH</param>
        /// <param name="abit">仲裁域波特率</param>
        /// <param name="dbit">数据域波特率</param>
        /// <param name="Resistance">是否使能终端电阻</param>
        /// <param name="lvbo">滤波0标准帧，1扩展帧，2禁能</param>
        /// <param name="startid">起始地址</param>
        /// <param name="endid">结束地址</param>
        /// <returns></returns>
        public static bool InitCan(int mode, int channel_index1, int index, int abit, int dbit, bool Resistance, int lvbo, string startid, string endid)
        {
            if (!m_bOpen)
            {
                MessageBox.Show("设备还没打开", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            channel_index = channel_index1;
            uint type = kDeviceType[8].device_type;
            bool tcpDevice = type == Define.ZCAN_CANETTCP || type == Define.ZCAN_CANFDNET_400U_TCP || type == Define.ZCAN_CANFDNET_200U_TCP || type == Define.ZCAN_CANFDNET_800U_TCP;
            //bool server = tcpDevice && id == 0;
            if (!setCANFDStandard(index)) //设置CANFD标准
            {
                MessageBox.Show("设置CANFD标准失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            bool result = true;

            if (type == Define.ZCAN_USBCANFD_200U)
            {
                string path = "0/set_device_recv_merge";
                string value = "0";
                Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
            }
            result = setFdBaudrate(kUSBCANFDAbit[abit], kUSBCANFDDbit[dbit]);


            ZCAN_CHANNEL_INIT_CONFIG config_ = new ZCAN_CHANNEL_INIT_CONFIG();
            config_.canfd.mode = (byte)mode;

            config_.can_type = Define.TYPE_CANFD;

            IntPtr pConfig = Marshal.AllocHGlobal(Marshal.SizeOf(config_));
            Marshal.StructureToPtr(config_, pConfig, true);
            channel_handle_ = Method.ZCAN_InitCAN(device_handle_, (uint)channel_index, pConfig);
            Marshal.FreeHGlobal(pConfig);
            if (NULL == (int)channel_handle_)
            {
                MessageBox.Show("初始化CAN失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            if (!setResistanceEnable(Resistance))
            {
                MessageBox.Show("使能终端电阻失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            if (!setFilter(lvbo, startid, endid))
            {
                MessageBox.Show("设置滤波失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            return true;
        }
        private bool setBaudrate(UInt32 baud)
        {
            string path = channel_index_ + "/baud_rate";
            string value = baud.ToString();
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
            return 1 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
        }

        private static bool setFdBaudrate(UInt32 abaud, UInt32 dbaud)
        {
            string path = channel_index_ + "/canfd_abit_baud_rate";
            string value = abaud.ToString();
            if (1 != Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value)))
            {
                return false;
            }
            path = channel_index_ + "/canfd_dbit_baud_rate";
            value = dbaud.ToString();
            if (1 != Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value)))
            {
                return false;
            }
            return true;
        }

        //设置CANFD标准
        private static bool setCANFDStandard(int canfd_standard)
        {
            string path = channel_index_ + "/canfd_standard";
            string value = canfd_standard.ToString();
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
            return 1 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
        }

        //设置自定义波特率, 需要从CANMaster目录下的baudcal生成字符串
        private bool setCustomBaudrate()
        {
            string path = channel_index_ + "/baud_rate_custom";
            string baudrate = "";
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(baudrate).ToPointer();
            return 1 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(baudrate));
        }

        //设置终端电阻使能
        private static bool setResistanceEnable(bool falg)
        {
            string path = channel_index_ + "/initenal_resistance";
            string value = (falg ? "1" : "0");
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
            return 1 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
        }

        /// <summary>
        /// 设置滤波
        /// </summary>
        /// <param name="idex">滤波索引0标准帧，1扩展帧，2禁能</param>
        /// <param name="startid">起始ID</param>
        /// <param name="endid">结束ID</param>
        /// <returns></returns>
        private static bool setFilter(int idex, string startid, string endid)
        {
            string path = channel_index_ + "/filter_clear";//清除滤波
            string value = "0";
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
            if (0 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value)))
            {
                return false;
            }

            path = channel_index_ + "/filter_mode";
            value = idex.ToString();
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
            if (value == "2")
            {
                return true;
            }
            if (0 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value)))
            {
                return false;
            }

            path = channel_index_ + "/filter_start";
            value = startid;
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
            if (0 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value)))
            {
                return false;
            }

            path = channel_index_ + "/filter_end";
            value = endid;
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
            if (0 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value)))
            {
                return false;
            }

            path = channel_index_ + "/filter_ack";//滤波生效
            value = "0";
            //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
            //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
            if (0 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value)))
            {
                return false;
            }

            //如果要设置多条滤波，在清除滤波和滤波生效之间设置多条滤波即可
            return true;
        }
        //设置网络工作模式
        private static bool setNetMode()
        {
            string path = channel_index + "/work_mode";
            string value = 1 == 0 ? "1" : "0";
            return 1 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
        }
        private static bool setLocalPort(string ip)
        {
            string path = channel_index + "/local_port";
            string value = ip;
            return 1 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
        }
        //设置远程地址
        private static bool setRemoteAddr(string ip)
        {
            string path = channel_index + "/ip";
            string value = ip;
            return 1 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
        }
        //设置远程端口
        private static bool setRemotePort(string port)
        {
            string path = channel_index + "/work_port";
            string value = port;
            return 1 == Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
        }
        /// <summary>
        /// 启动can
        /// </summary>
        /// <returns></returns>
        public static Recvdatathread StartCan()
        {
            Console.WriteLine(Method.ZCAN_StartCAN(channel_handle_));
            if (Method.ZCAN_StartCAN(channel_handle_) != Define.STATUS_OK)
            {
                MessageBox.Show("启动CAN失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return null;
            }
            if (null == recv_data_thread_)
            {
                recv_data_thread_ = new Recvdatathread();
                recv_data_thread_.setChannelHandle(channel_handle_);
                recv_data_thread_.setStart(true);
                //recv_data_thread_.RecvCANData += Recv_data_thread__RecvCANData;
                //recv_data_thread_.RecvFDData += this.AddData;
                return recv_data_thread_;
            }
            else
            {
                recv_data_thread_.setChannelHandle(channel_handle_);
                return null;
            }
        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="data">字符串数据</param>
        /// <param name="id">id号</param>
        /// <param name="frametypeindex">帧类型/0为标准帧/1为扩展帧</param>
        /// <param name="protocolindex">数据协议/0为can协议1为canfd</param>
        /// <param name="sendtype">发送方式/0为正常发送1单次发送2自发自收3为单次自发自收</param>
        /// <param name="canfdexpindex">CANFD加速/0为不加速1为加速</param>
        /// <returns></returns>
        public static bool SendData(string data, string id, int frametypeindex, int protocolindex, int sendtype, int canfdexpindex)
        {
            try
            {
                if (data.Length == 0)
                {
                    MessageBox.Show("数据为空", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return false;
                }
                if (!m_bOpen)
                {
                    MessageBox.Show("设备还没打开", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return false;
                }
                uint result; //发送的帧数
                if (protocolindex == 0)
                {
                    ZCAN_Transmit_Data can_data = new ZCAN_Transmit_Data();
                    can_data.frame.can_id = MakeCanId((uint)System.Convert.ToInt32(id, 16), frametypeindex, 0, 0);
                    can_data.frame.data = new byte[8];
                    can_data.frame.can_dlc = (byte)SplitData(data, ref can_data.frame.data, 8);
                    can_data.transmit_type = (uint)sendtype;
                    IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(can_data));
                    Marshal.StructureToPtr(can_data, ptr, true);
                    result = Method.ZCAN_Transmit(channel_handle_, ptr, 1);
                    Marshal.FreeHGlobal(ptr);
                }
                else
                {
                    ZCAN_TransmitFD_Data canfd_data = new ZCAN_TransmitFD_Data();
                    //string id = "00000001";//id
                    canfd_data.frame.can_id = MakeCanId((uint)System.Convert.ToInt32(id, 16), frametypeindex, 0, 0);
                    canfd_data.frame.data = new byte[64];
                    canfd_data.frame.len = (byte)SplitData(data, ref canfd_data.frame.data, 64);
                    //int sendtype = 0;//发送方式0为正常发送1单次发送
                    canfd_data.transmit_type = (uint)sendtype;
                    canfd_data.frame.flags = (byte)((canfdexpindex != 0) ? CANFD_BRS : 0);
                    IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(canfd_data));
                    Marshal.StructureToPtr(canfd_data, ptr, true);
                    result = Method.ZCAN_TransmitFD(channel_handle_, ptr, 1);
                    Marshal.FreeHGlobal(ptr);
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }


        }
        private static int SplitData(string data, ref byte[] transData, int maxLen)
        {
            string[] dataArray = data.Split(' ');
            for (int i = 0; (i < maxLen) && (i < dataArray.Length); i++)
            {
                transData[i] = Convert.ToByte(dataArray[i].Substring(0, 2), 16);
            }

            return dataArray.Length;
        }
        /// <summary>
        /// 转换can id
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="eff">帧类型</param>
        /// <param name="rtr"></param>
        /// <param name="err"></param>
        /// <returns></returns>
        public static uint MakeCanId(uint id, int eff, int rtr, int err)//1:extend frame 0:standard frame
        {
            uint ueff = (uint)(!!(Convert.ToBoolean(eff)) ? 1 : 0);
            uint urtr = (uint)(!!(Convert.ToBoolean(rtr)) ? 1 : 0);
            uint uerr = (uint)(!!(Convert.ToBoolean(err)) ? 1 : 0);
            return id | ueff << 31 | urtr << 30 | uerr << 29;
        }
        /// <summary>
        /// 复位
        /// </summary>
        /// <returns></returns>
        public static bool Reset()
        {
            string path = channel_index + "/clear_auto_send";
            string value = "0";
            uint result = Method.ZCAN_SetValue(device_handle_, path, Encoding.ASCII.GetBytes(value));
            if (Method.ZCAN_ResetCAN(channel_handle_) != Define.STATUS_OK)
            {
                MessageBox.Show("复位失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            return true;
        }
        /// <summary>
        /// 关闭设备
        /// </summary>
        public static void CloseDevice()
        {
            Method.ZCAN_CloseDevice(device_handle_);
            m_bOpen = false;
        }
        static byte iterations;
        static uint wLastSeed;
        static uint wTemp = 0;

        /// <summary>
        /// 安全常数
        /// </summary>
        public const uint SUPPLIER_6162_SECURITY_MASK = 0x12345678;

        /// <summary>
        /// 生成密钥
        /// </summary>
        /// <param name="cSeed"></param>
        /// <param name="cSecurityconstant"></param>
        /// <returns></returns>
        public static uint SecretKey(uint cSeed, uint cSecurityconstant)
        {
            uint wLSBit;
            uint wTop31Bits;
            byte jj, SB1, SB2, SB3;
            int temp;
            wLastSeed = cSeed;
            temp = (int)((int)((cSecurityconstant & 0x00000800) >> 10) | ((cSecurityconstant & 0x00200000) >> 21));
            switch (temp)
            {
                case 0:
                    wTemp = (byte)((cSeed & 0xff000000) >> 24);
                    break;
                case 1:
                    wTemp = (byte)((cSeed & 0x00ff0000) >> 16);
                    break;
                case 2:
                    wTemp = (byte)((cSeed & 0x0000ff00) >> 8);
                    break;
                case 3:
                    wTemp = (byte)(cSeed & 0x000000ff);
                    break;
            }
            SB1 = (byte)((cSecurityconstant & 0x000003FC) >> 2);
            SB2 = (byte)(((cSecurityconstant & 0x7F800000) >> 23) ^ 0xA5);
            SB3 = (byte)(((cSecurityconstant & 0x001FE000) >> 13) ^ 0x5A);
            iterations = (byte)(uint)(((wTemp ^ SB1) & SB2) + SB3);

            iterations = (byte)(((wTemp ^ SB1) & SB2) + SB3);
            for (jj = 0; jj < iterations; jj++)
            {
                wTemp = ((wLastSeed & 0x40000000) / 0x40000000) ^ ((wLastSeed & 0x01000000) / 0x01000000) ^ ((wLastSeed &
                0x1000) / 0x1000) ^ ((wLastSeed & 0x04) / 0x04);
                wLSBit = (wTemp & 0x00000001);
                wLastSeed = (uint)(int)(wLastSeed << 1); /* Left Shift the bits */
                wTop31Bits = (uint)(int)(wLastSeed & 0xFFFFFFFE);
                wLastSeed = (uint)(int)(wTop31Bits | wLSBit);
            }
            if (cSecurityconstant == 0x00000001)
            {
                wTop31Bits = ((wLastSeed & 0x00FF0000) >> 16) | // KEY[0] = Last_Seed[1] 
                ((wLastSeed & 0xFF000000) >> 8) | // KEY[1] = Last_Seed[0] 
                ((wLastSeed & 0x000000FF) << 8) | // KEY[2] = Last_Seed[3] 
                ((wLastSeed & 0x0000FF00) << 16); // KEY[3] = Last_Seed[2] 
            }
            else
                wTop31Bits = wLastSeed;
            wTop31Bits = wTop31Bits ^ cSecurityconstant;
            return (wTop31Bits);
        }



        /// <summary>
        /// 延时
        /// </summary>
        /// <param name="timer"></param>
        protected static void Delay(int timer)
        {
            int start = Environment.TickCount;
            while (Math.Abs(Environment.TickCount - start) < timer)
            {
                System.Windows.Forms.Application.DoEvents();
            }
        }
        /// <summary>
        /// 默认会话
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="zLGCANHelper"></param>
        /// <param name="zCAN_Receive_Datas"></param>
        /// <returns></returns>
        public static string[] DefaultSession(int channel, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas)
        {
            zLGCANHelper.SentData(channel, 0x761, "02 10 01 00 00 00 00 00", false, SendType.正常发送);
            eLog.AddLog($"进入默认会话发送：02 10 01 00 00 00 00 00", eMsgType.Debug);
            zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 1);
            string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
            eLog.AddLog($"进入默认会话响应：{string.Join(",", datas)}", eMsgType.Debug);
            if (datas.Length != 0)
            {
                return datas;
            }
            return null;
        }
        /// <summary>
        /// 扩展会话
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="zLGCANHelper"></param>
        /// <param name="zCAN_Receive_Datas"></param>
        /// <returns></returns>
        public static string[] ExpandSession(int channel, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas)
        {
            zLGCANHelper.SentData(channel, 0x761, "02 10 03 00 00 00 00 00", false, SendType.正常发送);
            eLog.AddLog($"进入扩展会话发送：02 10 03 00 00 00 00 00", eMsgType.Debug);
            zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 1);
            string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
          
            eLog.AddLog($"进入扩展会话响应：{string.Join(",", datas)}", eMsgType.Debug);
            if (datas.Length != 0)
            {
                return datas;
            }
            return null;
        }
        /// <summary>
        /// 进工厂模式
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="zLGCANHelper"></param>
        /// <param name="zCAN_Receive_Datas"></param>
        /// <returns></returns>
        public static string[] FactoryEntryMode(int channel, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas)
        {
            zLGCANHelper.SentData(channel, 0x761, "02 10 60 00 00 00 00 00", false, SendType.正常发送);
            eLog.AddLog($"进入工厂模式发送：02 10 60 00 00 00 00 00", eMsgType.Debug);
            zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 1);
            string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
            eLog.AddLog($"进入工厂模式响应：{string.Join(",", datas)}", eMsgType.Debug);
            if (datas.Length != 0)
            {
                return datas;
            }
            return null;
        }
        /// <summary>
        /// 请求种子
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="zLGCANHelper"></param>
        /// <param name="zCAN_Receive_Datas"></param>
        /// <returns></returns>
        public static string RequestSeed01(int channel, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas)
        {
            zLGCANHelper.SentData(channel, 0x761, "02 27 01 00 00 00 00 00", false, SendType.正常发送);
            eLog.AddLog($"请求种子发送：02 27 01 00 00 00 00 00", eMsgType.Debug);
            zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 1);
            string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
            eLog.AddLog($"请求种子响应：{string.Join(",", datas)}", eMsgType.Debug);
            if (datas[0].Split(' ')[1] == "67" && datas[0].Split(' ')[2] == "01")
            {
                uint seed = (uint)(Convert.ToInt32(datas[0].Split(' ')[6], 16) |
                    Convert.ToInt32(datas[0].Split(' ')[5], 16) << 8 |
                    Convert.ToInt32(datas[0].Split(' ')[4], 16) << 16 |
                    Convert.ToInt32(datas[0].Split(' ')[3], 16) << 24);//获取种子
                //uint vale = SecretKey(seed, SUPPLIER_6162_SECURITY_MASK);//生成密钥
                //       
                //Console.WriteLine("种子:" + vale);
                //byte[]data = new byte[] { Convert.ToByte(datas[0].Split(' ')[3]), Convert.ToByte(datas[0].Split(' ')[4]), Convert.ToByte(datas[0].Split(' ')[5]), Convert.ToByte(datas[0].Split(' ')[6]) };
                byte[] data = new byte[] { Convert.ToByte(datas[0].Split(' ')[3], 16), Convert.ToByte(datas[0].Split(' ')[4], 16), Convert.ToByte(datas[0].Split(' ')[5], 16), Convert.ToByte(datas[0].Split(' ')[6], 16) };
                //byte[] bpara = System.BitConverter.GetBytes(seed);

                string vale = get3EKey01(data, 0x1);


                //string valueOut;
                //SendSeed.GetIoKeyArray(seed, out valueOut);

                //byte[] be = new byte[4];
                //be[3] = (byte)(vale);
                //be[2] = (byte)(vale >> 8);
                //be[1] = (byte)(vale >> 16);
                //be[0] = (byte)(vale >> 24);
                string key = string.Format("06 27 02 {0:x2} {1:x2} {2:x2} {3:x2} 00", vale.Substring(0, 2), vale.Substring(2, 2), vale.Substring(4, 2), vale.Substring(6, 2));
                return key;
                //string result = "06 27 62" + valueOut;
                //return result;
            }
            else
            {
                return null;
            }

        }

        /// <summary>
        /// 请求种子
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="zLGCANHelper"></param>
        /// <param name="zCAN_Receive_Datas"></param>
        /// <returns></returns>
        public static string RequestSeed61(int channel, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas)
        {
            zLGCANHelper.SentData(channel, 0x761, "02 27 61 00 00 00 00 00", false, SendType.正常发送);
            eLog.AddLog($"请求种子61发送：02 27 61 00 00 00 00 00", eMsgType.Debug);
            zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 1);
            string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
            eLog.AddLog($"请求种子61响应：{string.Join(",", datas)}", eMsgType.Debug);
            if (datas[0].Split(' ')[1] == "67" && datas[0].Split(' ')[2] == "61")
            {
                uint seed = (uint)(Convert.ToInt32(datas[0].Split(' ')[6], 16) |
                    Convert.ToInt32(datas[0].Split(' ')[5], 16) << 8 |
                    Convert.ToInt32(datas[0].Split(' ')[4], 16) << 16 |
                    Convert.ToInt32(datas[0].Split(' ')[3], 16) << 24);//获取种子
                //uint vale = SecretKey(seed, SUPPLIER_6162_SECURITY_MASK);//生成密钥
                //       
                //Console.WriteLine("种子:" + vale);
                //byte[]data = new byte[] { Convert.ToByte(datas[0].Split(' ')[3]), Convert.ToByte(datas[0].Split(' ')[4]), Convert.ToByte(datas[0].Split(' ')[5]), Convert.ToByte(datas[0].Split(' ')[6]) };
                byte[] data = new byte[] { Convert.ToByte(datas[0].Split(' ')[3], 16), Convert.ToByte(datas[0].Split(' ')[4], 16), Convert.ToByte(datas[0].Split(' ')[5], 16), Convert.ToByte(datas[0].Split(' ')[6], 16) };
                //byte[] bpara = System.BitConverter.GetBytes(seed);

                string vale = get3EKey01(data, 0x61);
                //string valueOut;
                //SendSeed.GetIoKeyArray(seed, out valueOut);
                //byte[] be = new byte[4];
                //be[3] = (byte)(vale);
                //be[2] = (byte)(vale >> 8);
                //be[1] = (byte)(vale >> 16);
                //be[0] = (byte)(vale >> 24);
                string key = string.Format("06 27 62 {0:x2} {1:x2} {2:x2} {3:x2} 00", vale.Substring(0, 2), vale.Substring(2, 2), vale.Substring(4, 2), vale.Substring(6, 2));
                return key;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 发送密钥
        /// </summary>
        /// <param name="channel">通道</param>
        /// <param name="zLGCANHelper"></param>
        /// <param name="zCAN_Receive_Datas"></param>
        /// <param name="key">密钥</param>
        /// <returns></returns>
        public static string[] SendKey(int channel, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas, string key)
        {
            zLGCANHelper.SentData(channel, 0x761, key, false, SendType.正常发送);
            eLog.AddLog($"发送密钥：{key}", eMsgType.Debug);
            zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 1);
            string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
            eLog.AddLog($"发送密钥响应：{string.Join(",", datas)}", eMsgType.Debug);
            if (datas.Length != 0)
            {
                return datas;
            }
            return null;
        }
        /// <summary>
        /// 进入会话模式
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="zLGCANHelper"></param>
        /// <param name="zCAN_Receive_Datas"></param>
        /// <returns></returns>
        public static Dictionary<bool, string> EntryMODE(int channel, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas, string 安全级别)
        {
            List<string[]> list;
            if (安全级别 == "01")
            {
                list = new List<string[]>
                {
                 
                //DefaultSession(channel, zLGCANHelper, zCAN_Receive_Datas),
                     ExpandSession(channel, zLGCANHelper, zCAN_Receive_Datas),
                    //FactoryEntryMode(channel, zLGCANHelper, zCAN_Receive_Datas),
                };
            }
            else
            {
                list = new List<string[]>
                {

                    DefaultSession(channel, zLGCANHelper, zCAN_Receive_Datas),
                    ExpandSession(channel, zLGCANHelper, zCAN_Receive_Datas),
                    FactoryEntryMode(channel, zLGCANHelper, zCAN_Receive_Datas),
                };
            }

            Dictionary<bool, string> keyValues = new Dictionary<bool, string>();
            for (int i = 0; i < list.Count; i++)
            {
                string strVal = list[i][0].Split(' ')[1].ToString() + list[i][0].Split(' ')[2].ToString();
                switch (strVal)
                {
                    case "5001":
                        break;
                    case "5003":
                        break;
                    case "5060":
                        break;
                    default:
                        switch (i)
                        {
                            case 0:
                                keyValues.Add(false, "进入默认会话失败");
                                eLog.AddLog($"解密失败，进入默认会话失败", eMsgType.Error);
                                return keyValues;
                            case 1:
                                keyValues.Add(false, "进入扩展会话失败");
                                eLog.AddLog($"解密失败，进入扩展会话失败", eMsgType.Error);
                                return keyValues;
                            case 2:
                                keyValues.Add(false, "进入工厂模式失败");
                                eLog.AddLog($"解密失败，进入工厂模式失败", eMsgType.Error);
                                return keyValues;
                        }
                        break;
                }
            }
            string keys;
            string keysstr = "";
            if (安全级别 == "01")
            {
                keys = RequestSeed01(channel, zLGCANHelper, zCAN_Receive_Datas);
                keysstr = "02";
            }
            else
            {
                keysstr = "62";
                keys = RequestSeed61(channel, zLGCANHelper, zCAN_Receive_Datas);
            }

            if (keys == null)
            {
                keyValues.Add(false, "请求种子失败");
                eLog.AddLog($"解密失败，请求种子失败", eMsgType.Error);
                return keyValues;
            }

            var retValue = SendKey(channel, zLGCANHelper, zCAN_Receive_Datas, keys);
           
            if (retValue[0].Split(' ')[1] != "67" && retValue[0].Split(' ')[2] != keysstr)
            {
                keyValues.Add(false, "发送密钥失败");
                eLog.AddLog($"解密失败，发送密钥失败", eMsgType.Error);
                return keyValues;
            }
            keyValues.Add(true, "发送密钥success");

            return keyValues;
        }

        /// <summary>
        /// 获取SN
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="zLGCANHelper"></param>
        /// <param name="zCAN_Receive_Datas"></param>
        /// <returns></returns>
        public static string GetSN(int channel, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas, out string 信息)
        {
            try
            {
                zLGCANHelper.SentData(channel, 0x761, "03 22 F1 8C 00 00 00 00", true, SendType.正常发送);
                Delay(80);
                zLGCANHelper.SentData(channel, 0x761, "30 08 14 00 00 00 00 00", true, SendType.正常发送);
                Delay(100);
                zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 3, 1500);
                string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);
                //03 7F 22 78 AA AA AA AA ,10 13 62 F1 8C 20 37 46 ,21 37 32 31 30 43 52 41 ,22 32 38 30 30 31 37 AA 
                Delay(50);
                string[] hexValues = new string[15];
                int num = 0;
                bool ok10 = false;
                bool ok21 = false;
                bool ok22 = false;
                foreach (string s in datas)
                {
                    if (s.Trim().StartsWith("10"))
                    {
                        ok10 = true;
                        for (int i = 0; i < s.Split(' ').Length; i++)
                        {
                            if (i <= 5 || i > 7) continue;
                            hexValues[num] = s.Split(' ')[i];
                            num++;
                        }
                    }
                    else if (s.Trim().StartsWith("21"))
                    {
                        ok21 = true;
                        for (int i = 0; i < s.Split(' ').Length; i++)
                        {
                            if (i == 0 || i > 7) continue;
                            hexValues[num] = s.Split(' ')[i];
                            num++;
                        }
                    }
                    else if (s.Trim().StartsWith("22"))
                    {
                        ok22 = true;
                        for (int i = 0; i < s.Split(' ').Length; i++)
                        {
                            if (i == 0 || i > 6) continue;
                            hexValues[num] = s.Split(' ')[i];
                            num++;
                        }
                    }
                }

                var hexValues0 = "";
                if (!ok10 || !ok21 || !ok22)
                {
                    信息 = string.Join(",", datas);
                    return "";
                }


                foreach (String hex in hexValues)
                {
                    int value = Convert.ToInt32(hex, 16);
                    string stringValue = Char.ConvertFromUtf32(value);
                    hexValues0 += stringValue;
                }
                信息 = string.Join(",", datas);
                return hexValues0;
            }
            catch (Exception ex)
            {
                信息 = "获取SN失败：" + ex.Message;
                return null;
            }
        }

        public static string 获取ECU应用软件(int channel, ECU应用软件Enum eCU, ZLGCANHelper zLGCANHelper, List<ZCAN_Receive_Data> zCAN_Receive_Datas, out string 信息)
        {
#if ELO20240927
            //两个版本的代码看起来是一样的，先留着，2024-11-22
            try
            {
                string ECU应用软件号 = "";
                string str = "";
                switch (eCU)
                {
                    case ECU应用软件Enum.二级://
                        str = "03 22 F1 B5 00 00 00 00";
                        break;
                    case ECU应用软件Enum.三级:
                        str = "03 22 F1 B6 00 00 00 00";
                        break;
                    case ECU应用软件Enum.四级:
                        str = "03 22 F1 B7 00 00 00 00";
                        break;
                    case ECU应用软件Enum.五级:
                        str = "03 22 F1 B8 00 00 00 00";
                        break;
                    case ECU应用软件Enum.六级:
                        str = "03 22 F1 B9 00 00 00 00";
                        break;
                    default:
                        str = "03 22 F1 B5 00 00 00 00";
                        break;
                }
                zLGCANHelper.SentData(channel, 0x761, str, true, SendType.正常发送);
                Delay(80);
                zLGCANHelper.SentData(channel, 0x761, "30 08 14 00 00 00 00 00", true, SendType.正常发送);

                zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 3, 1500);
                string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);

                string[] hexValues = new string[5];
                int num = 0;
                bool ok10 = false;
                bool ok21 = false;
                foreach (string s in datas)
                {
                    if (s.Trim().StartsWith("10"))
                    {
                        ok10 = true;
                        for (int i = 0; i < s.Split(' ').Length; i++)
                        {
                            if (i < 5 || i > 7) continue;
                            hexValues[num] = s.Split(' ')[i];
                            num++;
                        }
                    }
                    else if (s.Trim().StartsWith("21"))
                    {
                        ok21 = true;
                        for (int i = 0; i < s.Split(' ').Length; i++)
                        {
                            if (i == 0 || i > 2) continue;
                            hexValues[num] = s.Split(' ')[i];
                            num++;
                        }
                    }
                }
                var hexValues0 = "";
                if (!ok10 || !ok21)
                {
                    信息 = string.Join(",", datas);
                    return "";
                }


                foreach (String hex in hexValues)
                {
                    int value = Convert.ToInt32(hex, 16);
                    string stringValue = Char.ConvertFromUtf32(value);
                    hexValues0 += stringValue;
                }
                ECU应用软件号 = String.Join("", hexValues.ToList().GetRange(0, 4)).Trim() + "/" + hexValues[4];
                信息 = string.Join(",", datas);
                return ECU应用软件号;
            }
            catch (Exception ex)
            {
                信息 = "获取ECU应用软件失败：" + ex.Message;
                return null;
            }
#else
            try
            {
                string ECU应用软件号 = "";
                string str = "";
                switch (eCU)
                {
                    case ECU应用软件.二级://
                        str = "03 22 F1 B5 00 00 00 00";
                        break;
                    case ECU应用软件.三级:
                        str = "03 22 F1 B6 00 00 00 00";
                        break;
                    case ECU应用软件.四级:
                        str = "03 22 F1 B7 00 00 00 00";
                        break;
                    case ECU应用软件.五级:
                        str = "03 22 F1 B8 00 00 00 00";
                        break;
                    case ECU应用软件.六级:
                        str = "03 22 F1 B9 00 00 00 00";
                        break;
                    default:
                        str = "03 22 F1 B5 00 00 00 00";
                        break;
                }
                zLGCANHelper.SentData(channel, 0x761, str, true, SendType.正常发送);
                Delay(80);
                zLGCANHelper.SentData(channel, 0x761, "30 08 14 00 00 00 00 00", true, SendType.正常发送);

                zCAN_Receive_Datas = zLGCANHelper.RecvData(channel, 0x769, 3, 1500);
                string[] datas = ZLGCanTool.GetData(zCAN_Receive_Datas);

                string[] hexValues = new string[5];
                int num = 0;
                bool ok10 = false;
                bool ok21 = false;
                foreach (string s in datas)
                {
                    if (s.Trim().StartsWith("10"))
                    {
                        ok10 = true;
                        for (int i = 0; i < s.Split(' ').Length; i++)
                        {
                            if (i < 5 || i > 7) continue;
                            hexValues[num] = s.Split(' ')[i];
                            num++;
                        }
                    }
                    else if (s.Trim().StartsWith("21"))
                    {
                        ok21 = true;
                        for (int i = 0; i < s.Split(' ').Length; i++)
                        {
                            if (i == 0 || i > 2) continue;
                            hexValues[num] = s.Split(' ')[i];
                            num++;
                        }
                    }
                }
                var hexValues0 = "";
                if (!ok10 || !ok21)
                {
                    信息 = string.Join(",", datas);
                    return "";
                }


                foreach (String hex in hexValues)
                {
                    int value = Convert.ToInt32(hex, 16);
                    string stringValue = Char.ConvertFromUtf32(value);
                    hexValues0 += stringValue;
                }
                ECU应用软件号 = String.Join("", hexValues.ToList().GetRange(0, 4)).Trim() + "/" + hexValues[4];
                信息 = string.Join(",", datas);
                return ECU应用软件号;
            }
            catch (Exception ex)
            {
                信息 = "获取ECU应用软件失败：" + ex.Message;
                return null;
            }
#endif
        }

        /// <summary>
        /// 通道
        /// </summary>
        private int channel { get; set; }

        /// <summary>
        /// CAN盒IP地址
        /// </summary>
        public string RemoteAddr { get; set; }

        /// <summary>
        /// CAN盒Port
        /// </summary>
        public int RemotePort { get; set; }
        public ZLGCANHelper canFactory { get; set; }
        public CanFactory(string ip, int port, int channel, ZLGCANHelper canFactory)
        {
            this.RemoteAddr = ip;
            this.RemotePort = port;
            this.channel = channel;
            this.canFactory = canFactory;
        }
        static IntPtr intPtr;
        /// <summary>
        /// 打开多路can通道
        /// </summary>
        /// <param name="Ip"></param>
        /// <param name="Port"></param>
        /// <param name="num"></param>
        /// <param name="zLGCANHelper"></param>
        /// <returns></returns>
        public static List<CanFactory> MultiplexerChannel(string Ip, int Port, int num, ZLGCANHelper zLGCANHelper)
        {
            IntPtr device_handle_ = zLGCANHelper.Opens(0);
            if ((int)device_handle_ == 0)
            {
                zLGCANHelper.Logger?.Invoke("索引为0的CAN盒打开失败");
                return null;
            }
            List<CanFactory> list = new List<CanFactory>();
            for (int i = 0; i < num; i++)
            {
                ZLGCANHelper canFactory = new ZLGCANHelper(device_handle_);
                CanFactory can = new CanFactory(Ip, Port, i, canFactory);
                intPtr = can.Inits(0, zLGCANHelper);

                bool StartOk = can.Start(intPtr, zLGCANHelper);
                list.Add(can);
            }
            return list;
        }
        private IntPtr Inits(int channel, ZLGCANHelper zLGCANHelper)
        {
            return zLGCANHelper.Init(channel);
        }

        private bool Start(IntPtr channel_handle_, ZLGCANHelper zLGCANHelper)
        {
            return zLGCANHelper.Start(channel_handle_);
        }

    }
}
